
import 'package:im_flutter_sdk/im_flutter_sdk.dart';

enum YKFHxIMOffLineType {
  LoginFromOtherDevice,
  RemoveFromServer,
  BidByServer,
  DidForcedToLogout,
}

enum YKFHxIMConnectTokenType {
  WillExpire,
  DidExpire
}

class YKFHxIMLogDelegate {
  void Function(String msg)? errorCallBack;
  void Function(String msg)? logCallBack;
  YKFHxIMLogDelegate({this.errorCallBack, this.logCallBack});
}

class YKFHxIMConnectDelegate {

  void Function(bool connected)? connectStatusCallBack;
  void Function(YKFHxIMOffLineType type)? offlineCallBack;
  void Function(YKFHxIMConnectTokenType type)? tokenTypeCallBack;
  YKFHxIMConnectDelegate({this.connectStatusCallBack, this.offlineCallBack, this.tokenTypeCallBack});
}

class YKFHxIM {

  static YKFHxIM? _instance_;
  static YKFHxIM get _instance => _instance_ ??= YKFHxIM._();
  YKFHxIM._();

  YKFHxIMLogDelegate? _logDelegate;
  YKFHxIMConnectDelegate? _connectDelegate;

  static init(String appKey, {YKFHxIMConnectDelegate? connectDelegate, YKFHxIMLogDelegate? logDelegate}) async {
    YKFHxIM._instance._connectDelegate = connectDelegate;
    YKFHxIM._instance._logDelegate = logDelegate;
    _addConnectionEventHandler();
    await EMClient.getInstance.init(EMOptions(appKey: appKey, autoLogin: true));
    await EMClient.getInstance.startCallback();
  }

  static login(String userName, String token, {void Function()? complateCallBack}) async {
    if (userName.isEmpty || token.isEmpty) {
      _error("不能为空");
      return;
    }
    try {
      await EMClient.getInstance.loginWithToken(userName, token);
      _log("登录成功");
      complateCallBack?.call();
    } catch (e) {
      _error(e.toString());
    }
  }

  static logout({void Function()? complateCallBack}) async {
    try {
      await EMClient.getInstance.logout(true);
      _log("退出登录成功");
      complateCallBack?.call();
    } catch (e) {
      _error(e.toString());
    }
  }

  static _addConnectionEventHandler() {
    // 注册连接状态监听
    EMClient.getInstance.addConnectionEventHandler(
      "UNIQUE_HANDLER_ID",
      EMConnectionEventHandler(
        // sdk 连接成功;
        onConnected: () {
          YKFHxIM._instance._connectDelegate?.connectStatusCallBack?.call(true);
        },
        // 由于网络问题导致的断开，sdk会尝试自动重连，连接成功后会回调 "onConnected";
        onDisconnected: () {
          YKFHxIM._instance._connectDelegate?.connectStatusCallBack?.call(false);
        },
        // 用户 token 鉴权失败;
        onUserAuthenticationFailed: () {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.DidForcedToLogout);
        },
        // 由于密码变更被踢下线;
        onUserDidChangePassword: () {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.DidForcedToLogout);
        },
        // 用户登录设备超出数量限制;
        onUserDidLoginTooManyDevice: () {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.DidForcedToLogout);
        },
        // 用户被连接被服务器禁止;
        onUserDidForbidByServer: () {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.BidByServer);
        },
        // 用户从服务器删除;
        onUserDidRemoveFromServer: () {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.RemoveFromServer);
        },
        // 调用 `kickDevice` 方法将设备踢下线，被踢设备会收到该回调；
        onUserKickedByOtherDevice: () {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.LoginFromOtherDevice);
        },
        // 登录新设备时因达到了登录设备数量限制而导致当前设备被踢下线，被踢设备收到该回调；
        onUserDidLoginFromOtherDevice: (String deviceName) {
          YKFHxIM._instance._connectDelegate?.offlineCallBack?.call(YKFHxIMOffLineType.LoginFromOtherDevice);
        },
        // Token 过期;
        onTokenDidExpire: () {
          YKFHxIM._instance._connectDelegate?.tokenTypeCallBack?.call(YKFHxIMConnectTokenType.DidExpire);
        },
        // Token 即将过期，需要调用 renewToken;
        onTokenWillExpire: () {
          YKFHxIM._instance._connectDelegate?.tokenTypeCallBack?.call(YKFHxIMConnectTokenType.WillExpire);
        },
      ),
    );

  }

  static _removeConnectionEventHandler() {

    // 解注册连接状态监听
    EMClient.getInstance.removeConnectionEventHandler(
      "UNIQUE_HANDLER_ID",
    );
  }


  static _error(String msg) {
    YKFHxIM._instance._logDelegate?.errorCallBack?.call(msg);
  }

  static _log(String msg) {
    YKFHxIM._instance._logDelegate?.logCallBack?.call(msg);
  }
}